﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.Unity;
using Apps.Models;
using Apps.Common;
using System.Transactions;
using Apps.Models.Flow;
using Apps.IBLL.Flow;
using Apps.IDAL.Flow;
using Apps.BLL.Core;
using Apps.Models.Enum;
using Apps.Locale;
using System.Linq.Expressions;

namespace Apps.BLL.Flow
{
    public partial class Flow_FormContentBLL
    {
        [Dependency]
        public IFlow_StepBLL stepBLL { get; set; }
        [Dependency]
        public IFlow_StepRuleBLL stepRuleBLL { get; set; }
        [Dependency]
        public IFlow_FormContentStepCheckBLL stepCheckBLL { get; set; }
        [Dependency]
        public IFlow_FormContentStepCheckStateBLL stepCheckStateBLL { get; set; }

        public List<Flow_FormContentModel> GetListByUserId(ref GridPager pager, string queryStr, string userId)
        {
            IQueryable<Flow_FormContent> queryData = null;
            if (!string.IsNullOrWhiteSpace(queryStr))
            {
                queryData = m_Rep.GetList(a => a.Title.Contains(queryStr) && a.UserId == userId);
            }
            else
            {
                queryData = m_Rep.GetList(a => a.UserId == userId);
            }
            pager.totalRows = queryData.Count();
            queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
            return CreateModelList(ref queryData);
        }

        public List<V_FLOW_STEPINFOModel> GetListByUserId(ref GridPager pager, string queryStr, string userId, int state)
        {
            using (DBContainer db = new DBContainer())
            {
                IQueryable<V_FLOW_STEPINFO> queryData = null;
                try
                {
                    switch (state)
                    {
                        case 0:
                            queryData = from v in db.V_FLOW_STEPINFO
                                        where v.STEPCHECKID == "00" && v.USERID == userId && (string.IsNullOrEmpty(queryStr) || v.TITLE.Contains(queryStr))
                                        select v;
                            break;
                        case 3://驳回
                            queryData = from v in db.V_FLOW_STEPINFO
                                        where v.STEPCHECKID == "00" && v.USERID == userId && v.STATE == 0 && (string.IsNullOrEmpty(queryStr) || v.TITLE.Contains(queryStr))
                                        select v;
                            break;
                        case 1://审批中
                            queryData = (from v0 in db.V_FLOW_STEPINFO
                                         join v1 in (from p in db.V_FLOW_STEPINFO where p.STEPCHECKID == "00" && p.USERID == userId && (string.IsNullOrEmpty(queryStr) || p.TITLE.Contains(queryStr)) select p)
                                         on v0.ID equals v1.ID
                                         where v0.STATE == 2
                                         select v1).Distinct();
                            break;
                        case 2://已通过
                            queryData = from s0 in db.V_FLOW_STEPINFO
                                        join s1 in (
                                          (from v0 in db.V_FLOW_STEPINFO
                                           join v1 in (from p in db.V_FLOW_STEPINFO where p.STEPCHECKID == "00" && p.USERID == userId select p)
                                           on v0.ID equals v1.ID
                                           where v0.STATE == 2
                                           select v1).Distinct()
                                         )
                                         on s0.ID equals s1.ID into TempInfo
                                        from s2 in TempInfo.DefaultIfEmpty()
                                        where s0.STEPCHECKID == "00" && s0.USERID == userId && s0.STATE != 0 && s2 == null && (string.IsNullOrEmpty(queryStr) || s0.TITLE.Contains(queryStr))
                                        select s0;
                            break;
                    }

                    pager.totalRows = queryData.Count();
                    queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
                    var list = queryData.ToList();
                    return TransHelper.TransExpList<V_FLOW_STEPINFO, V_FLOW_STEPINFOModel>(list);
                }
                catch (Exception)
                {
                    return null;
                }

            }
        }


        public virtual List<Flow_FormContentModel> GetPagerList(ref GridPager pager, Expression<Func<Flow_FormContent, bool>> whereLambda)
        {

            IQueryable<Flow_FormContent> queryData = m_Rep.GetList(whereLambda);

            pager.totalRows = queryData.Count();
            //排序
            queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
            return CreateModelList(ref queryData);
        }

        public List<Flow_FormContentModel> GeExaminetListByUserId(ref GridPager pager, string queryStr, string userId)
        {
            IQueryable<Flow_FormContent> queryData = null;
            if (!string.IsNullOrWhiteSpace(queryStr))
            {
                queryData = m_Rep.GeExamineListByUserId(userId).Where(a => a.Title.Contains(queryStr));
            }
            else
            {
                queryData = m_Rep.GeExamineListByUserId(userId);
            }
            pager.totalRows = queryData.Count();
            queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
            return CreateModelList(ref queryData);
        }

        public List<Flow_FormContentModel> GetMyExaminetListByUserId(ref GridPager pager, string queryStr, string userId)
        {
            IQueryable<Flow_FormContent> queryData = null;
            if (!string.IsNullOrWhiteSpace(queryStr))
            {
                queryData = m_Rep.GetMyExaminetListByUserId(userId).Where(a => a.Title.Contains(queryStr));
            }
            else
            {
                queryData = m_Rep.GetMyExaminetListByUserId(userId);
            }
            pager.totalRows = queryData.Count();
            queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
            return CreateModelList(ref queryData);
        }

        public List<V_FLOW_STEPINFOModel> GetMyExaminetListByUserId(ref GridPager pager, string queryStr, string userId, int state)
        {
            using (DBContainer db = new DBContainer())
            {

                IQueryable<V_FLOW_STEPINFO> queryData = null;
                try
                {
                    switch (state)
                    {
                        case 0:
                            queryData = (from t0 in db.V_FLOW_STEPINFO
                                         join t1 in db.V_FLOW_STEPINFO
                                         on t0.ID equals t1.ID
                                         where t0.STEPCHECKID == "00" && t1.USERID == userId && t1.STEPCHECKID != "00" && (string.IsNullOrEmpty(queryStr) || t0.TITLE.Contains(queryStr))
                                         select t0).Distinct();
                            break;
                        case 3://驳回
                            queryData = (from t0 in db.V_FLOW_STEPINFO
                                         join t1 in db.V_FLOW_STEPINFO
                                         on t0.ID equals t1.ID
                                         where t0.STEPCHECKID == "00" && t1.USERID == userId && t1.STEPCHECKID != "00" && t0.STATE == 0 && (string.IsNullOrEmpty(queryStr) || t0.TITLE.Contains(queryStr))
                                         select t0).Distinct();
                            break;
                        case 1://审批中
                            queryData = from a1 in
                                        (from t0 in db.V_FLOW_STEPINFO
                                         join t1 in db.V_FLOW_STEPINFO
                                         on t0.ID equals t1.ID
                                         where t0.STEPCHECKID == "00" && t1.USERID == userId && t1.STEPCHECKID != "00" && (string.IsNullOrEmpty(queryStr) || t0.TITLE.Contains(queryStr))
                                         select t0).Distinct()
                                        where (from p in db.V_FLOW_STEPINFO where p.STATE == 2 select p.ID).Distinct().Contains(a1.ID)
                                        select a1;
                            break;
                        case 2://已通过 
                            queryData = (from a1 in
                                          (from t0 in db.V_FLOW_STEPINFO
                                           join t1 in db.V_FLOW_STEPINFO
                                           on t0.ID equals t1.ID
                                           where t0.STEPCHECKID == "00" && t1.USERID == userId && t1.STEPCHECKID != "00" && t0.STATE != 0 && (string.IsNullOrEmpty(queryStr) || t0.TITLE.Contains(queryStr))
                                           select t0).Distinct()
                                         join a2 in (from p in db.V_FLOW_STEPINFO where p.STATE == 2 select p).Distinct()
                                         on a1.ID equals a2.ID into TempInfo
                                         from a3 in TempInfo.DefaultIfEmpty()
                                         where a3 == null
                                         select a1).Distinct();

                            //queryData = from a1 in
                            //           (from t0 in db.V_FLOW_STEPINFO
                            //            join t1 in db.V_FLOW_STEPINFO
                            //            on t0.ID equals t1.ID
                            //            where t0.STEPCHECKID == "00" && t1.USERID == userId && t1.STEPCHECKID != "00" && t0.STATE != 0 && (string.IsNullOrEmpty(queryStr) || t0.TITLE.Contains(queryStr))
                            //            select t0).Distinct()
                            //            where !(from p in db.V_FLOW_STEPINFO where p.STATE == 2 select p.ID).Distinct().Contains(a1.ID)
                            //            select a1;
                            break;
                    }

                    pager.totalRows = queryData.Count();
                    queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
                    var list = queryData.ToList();
                    return TransHelper.TransExpList<V_FLOW_STEPINFO, V_FLOW_STEPINFOModel>(list);
                }
                catch (Exception )
                {
                    return null;
                }

            }
        }


        public List<Flow_FormContentModel> GeExaminetFinishListByUserId(ref GridPager pager, string queryStr, string userId)
        {
            IQueryable<Flow_FormContent> queryData = null;
            if (!string.IsNullOrWhiteSpace(queryStr))
            {
                queryData = m_Rep.GeExamineFinishListByUserId(userId).Where(a => a.Title.Contains(queryStr));
            }
            else
            {
                queryData = m_Rep.GeExamineFinishListByUserId(userId);
            }
            pager.totalRows = queryData.Count();
            queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
            return CreateModelList(ref queryData);
        }


        public override List<Flow_FormContentModel> CreateModelList(ref IQueryable<Flow_FormContent> queryData)
        {

            List<Flow_FormContentModel> modelList = (from r in queryData
                                                     select new Flow_FormContentModel
                                                     {
                                                         Id = r.Id,
                                                         Title = r.Title,
                                                         UserId = r.UserId,
                                                         UserName = r.SysUser.TrueName,
                                                         FormId = r.FormId,
                                                         FormLevel = r.FormLevel,
                                                         CreateTime = r.CreateTime,
                                                         AttrA = r.AttrA,
                                                         AttrB = r.AttrB,
                                                         AttrC = r.AttrC,
                                                         AttrD = r.AttrD,
                                                         AttrE = r.AttrE,
                                                         AttrF = r.AttrF,
                                                         AttrG = r.AttrG,
                                                         AttrH = r.AttrH,
                                                         AttrI = r.AttrI,
                                                         AttrJ = r.AttrJ,
                                                         AttrK = r.AttrK,
                                                         AttrL = r.AttrL,
                                                         AttrM = r.AttrM,
                                                         AttrN = r.AttrN,
                                                         AttrO = r.AttrO,
                                                         AttrP = r.AttrP,
                                                         AttrQ = r.AttrQ,
                                                         AttrR = r.AttrR,
                                                         AttrS = r.AttrS,
                                                         AttrT = r.AttrT,
                                                         AttrU = r.AttrU,
                                                         AttrV = r.AttrV,
                                                         AttrW = r.AttrW,
                                                         AttrX = r.AttrX,
                                                         AttrY = r.AttrY,
                                                         AttrZ = r.AttrZ,
                                                         CustomMember = r.CustomMember,
                                                         TimeOut = r.TimeOut,
                                                         IsDelete = r.IsDelete,
                                                         ExternalURL = r.Flow_Form.ExternalURL,
                                                         IsExternal = r.Flow_Form.IsExternal
                                                     }).ToList();

            return modelList;
        }

        public List<Flow_FormContentModel> GeExaminetList(ref GridPager pager, string queryStr)
        {
            IQueryable<Flow_FormContent> queryData = null;
            if (!string.IsNullOrWhiteSpace(queryStr))
            {
                queryData = m_Rep.GeExamineList().Where(a => a.Title.Contains(queryStr));
            }
            else
            {
                queryData = m_Rep.GeExamineList();
            }
            pager.totalRows = queryData.Count();
            queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
            return CreateModelList(ref queryData);
        }

        public List<V_FLOW_STEPINFOModel> GeExaminetList(ref GridPager pager, string queryStr, string txtStartDate, string txtEndDate, int state)
        {
            //string userId = "";
            DateTime dtStartDate = DateTime.Now;
            DateTime dtEndDate = DateTime.Now;

            if (string.IsNullOrWhiteSpace(txtStartDate)) txtStartDate = "$--txtStartDate--$";
            else dtStartDate = Convert.ToDateTime(txtStartDate + " 00:00:00");

            if (string.IsNullOrWhiteSpace(txtEndDate)) txtEndDate = "$--txtEndDate--$";
            else dtEndDate = Convert.ToDateTime(txtEndDate + " 23:59:59");

            using (DBContainer db = new DBContainer())
            {
                IQueryable<V_FLOW_STEPINFO> queryData = null;
                try
                {
                    switch (state)
                    {
                        case 0:
                            queryData = from v in db.V_FLOW_STEPINFO
                                        where v.STEPCHECKID == "00"
                                        && (txtStartDate == "$--txtStartDate--$" || v.CREATETIME >= dtStartDate)
                                        && (txtEndDate == "$--txtEndDate--$" || v.CREATETIME <= dtEndDate)
                                        && (string.IsNullOrEmpty(queryStr) || v.TITLE.Contains(queryStr))
                                        select v;
                            break;
                        case 3://驳回
                            queryData = from v in db.V_FLOW_STEPINFO
                                        where v.STEPCHECKID == "00" && v.STATE == 0
                                        && (txtStartDate == "$--txtStartDate--$" || v.CREATETIME >= dtStartDate)
                                        && (txtEndDate == "$--txtEndDate--$" || v.CREATETIME <= dtEndDate)
                                        && (string.IsNullOrEmpty(queryStr) || v.TITLE.Contains(queryStr))
                                        select v;
                            break;
                        case 1://审批中
                               //--审批中 
                            queryData = (from v0 in db.V_FLOW_STEPINFO
                                         join v1 in (from p in db.V_FLOW_STEPINFO
                                                     where p.STEPCHECKID == "00"
                         && (txtStartDate == "$--txtStartDate--$" || p.CREATETIME >= dtStartDate)
                         && (txtEndDate == "$--txtEndDate--$" || p.CREATETIME <= dtEndDate)
                         && (string.IsNullOrEmpty(queryStr) || p.TITLE.Contains(queryStr))
                                                     select p)
                                         on v0.ID equals v1.ID
                                         where v0.STATE == 2
                                         select v1).Distinct();
                            break;
                        case 2://已通过 
                            queryData = from a1 in db.V_FLOW_STEPINFO
                                        where !(
                                        from t0 in db.V_FLOW_STEPINFO
                                        join t1 in (from p in db.V_FLOW_STEPINFO where p.STEPCHECKID == "00" select p)
                                        on t0.ID equals t1.ID
                                        where t0.STATE == 2
                                        select t1.ID
                                        ).Distinct().Contains(a1.ID)
                                        && a1.STEPCHECKID == "00" && a1.STATE != 0
                                        && (txtStartDate == "$--txtStartDate--$" || a1.CREATETIME >= dtStartDate)
                                        && (txtEndDate == "$--txtEndDate--$" || a1.CREATETIME <= dtEndDate)
                                        && (string.IsNullOrEmpty(queryStr) || a1.TITLE.Contains(queryStr))
                                        select a1;
                            break;
                    }

                    pager.totalRows = queryData.Count();
                    queryData = LinqHelper.SortingAndPaging(queryData, pager.sort, pager.order, pager.page, pager.rows);
                    var list = queryData.ToList();
                    return TransHelper.TransExpList<V_FLOW_STEPINFO, V_FLOW_STEPINFOModel>(list);
                }
                catch (Exception )
                {
                    return null;
                }

            }
        }



        public int GetCurrentFormState(Flow_FormContentModel model)
        {

            List<Flow_FormContentStepCheckModel> stepCheckModelList = stepCheckBLL.GetListByFormId(model.FormId, model.Id);

            var passList = from r in stepCheckModelList where r.State == (int)FlowStateEnum.Pass select r;
            if (passList.Count() == stepCheckModelList.Count())
            {
                return (int)FlowStateEnum.Pass;
            }

            var rejectList = from r in stepCheckModelList where r.State == (int)FlowStateEnum.Reject && r.StepId == "00" select r;
            if (rejectList.Count() > 0)
            {
                return (int)FlowStateEnum.Reject;
            }

            //if (model.TimeOut < ResultHelper.NowTime)
            //{
            //    return (int)FlowStateEnum.Closed;
            //}

            return (int)FlowStateEnum.Progress;
        }

        public int GetCurFormState(V_FLOW_STEPINFOModel model)
        {

            List<Flow_FormContentStepCheckModel> stepCheckModelList = stepCheckBLL.GetListByFormId(model.FORMID, model.ID);

            var passList = from r in stepCheckModelList where r.State == (int)FlowStateEnum.Pass select r;
            if (passList.Count() == stepCheckModelList.Count())
            {
                return (int)FlowStateEnum.Pass;
            }

            var rejectList = from r in stepCheckModelList where r.State == (int)FlowStateEnum.Reject && r.StepId == "00" select r;
            if (rejectList.Count() > 0)
            {
                return (int)FlowStateEnum.Reject;
            }

            //if (model.TimeOut < ResultHelper.NowTime)
            //{
            //    return (int)FlowStateEnum.Closed;
            //}

            return (int)FlowStateEnum.Progress;
        }

        public string GetCurFormStep(string contentid)
        {
            string stepName = GetCurrentFormStepModel(contentid).Name;
            if (!string.IsNullOrEmpty(stepName))
            {
                return stepName;
            }
            return "结束";
        }

        public string GetCurrentFormStep(Flow_FormContentModel model)
        {
            string stepName = GetCurrentFormStepModel(model.Id).Name;
            if (!string.IsNullOrEmpty(stepName))
            {
                return stepName;
            }
            return "结束";
        }


        public Flow_StepModel GetCurrentFormStepModel(string contentId)
        {
            //List<Flow_FormContentStepCheckModel> stepCheckModelList = stepCheckBLL.GetListByFormId(model.FormId, model.Id);
            //for (int i =0;i< stepCheckModelList.Count();i++)
            //{
            //    if (stepCheckModelList[i].State == (int)FlowStateEnum.Progress)
            //    {
            //        return stepBLL.GetById(stepCheckModelList[i].StepId);
            //    }
            //}
            var stepCheckModel = stepCheckBLL.GetItem(p => p.ContentId == contentId && p.State == 2);
            if (stepCheckModel != null)
            {
                if (stepCheckModel.StepId == "00")
                {
                    var stepmodel = new Flow_StepModel();
                    stepmodel.Name = "起草";
                    return stepmodel;
                }
                else
                {
                    return stepBLL.GetById(stepCheckModel.StepId);
                }

            }
            return new Flow_StepModel();
        }


        //获取环节所有信息
        public string GetCurrentStepCheckMes(ref GridPager pager, string formId, string contentId, string currentUserId)
        {
            string stepCheckMes = "";
            List<Flow_FormContentStepCheckModel> stepCheckModelList = stepCheckBLL.GetListByFormId(formId, contentId);
            for (int i = 0; i < stepCheckModelList.Count; i++)
            {
                List<Flow_FormContentStepCheckStateModel> stepCheckStateList = stepCheckStateBLL.GetListByStepCheckId(ref pager, stepCheckModelList[i].Id);
                stepCheckMes = stepCheckMes + "<tr><th style='width:150px'>第" + (i + 1) + "步--->审批人：</th><td><table >";
                foreach (Flow_FormContentStepCheckStateModel checkStateModel in stepCheckStateList)
                {
                    stepCheckMes += "<tr class='" + (checkStateModel.UserId == currentUserId ? "color-green" : "") + "'><td>" + checkStateModel.UserName + " </td><th style='width:90px'> 审批意见：</th><td>" + checkStateModel.Reamrk + "</td><th style='width:90px'>审批结果：</th><td>" + (checkStateModel.CheckFlag == (int)FlowStateEnum.Pass ? "通过" : checkStateModel.CheckFlag == (int)FlowStateEnum.Reject ? "驳回" : "审批中") + "</td></tr>";
                }
                if (stepCheckStateList.Count == 0)
                {
                    stepCheckMes += "<tr><td>【等待上一步审批】</td><th> </th><td></td><th></th><td></td></tr>";
                }
                stepCheckMes += "</table></td></tr>";
            }
            return stepCheckMes;
        }
        //获取当前环节的审批条
        public string GetCurrentStepCheckId(string formId, string contentId)
        {
            List<Flow_FormContentStepCheckModel> stepCheckModelList = stepCheckBLL.GetListByFormId(formId, contentId);
            return new FlowHelper().GetCurrentStepCheckIdByStepCheckModelList(stepCheckModelList);

        }

        public string GetCurStepCheckId(string formId, string contentId)
        {
            List<Flow_FormContentStepCheckModel> stepCheckModelList = stepCheckBLL.GetListByFormId(formId, contentId);
            return new FlowHelper().GetCurrentStepCheckIdByStepCheckModelList(stepCheckModelList);

        }

        public override Flow_FormContentModel GetById(object id)
        {
            if (IsExists(id))
            {
                Flow_FormContent entity = m_Rep.GetById(id);
                Flow_FormContentModel model = new Flow_FormContentModel();
                model.Id = entity.Id;
                model.Title = entity.Title;
                model.UserId = entity.UserId;
                model.UserName = entity.SysUser.UserName;
                model.TrueName = entity.SysUser.TrueName;
                model.PosName = entity.SysUser.SysPosition != null ? entity.SysUser.SysPosition.Name : "";
                model.DepName = entity.SysUser.SysStruct != null ? entity.SysUser.SysStruct.Name : ""; ;
                model.FormId = entity.FormId;
                model.FormLevel = entity.FormLevel;
                model.CreateTime = entity.CreateTime;
                model.AttrA = entity.AttrA;
                model.AttrB = entity.AttrB;
                model.AttrC = entity.AttrC;
                model.AttrD = entity.AttrD;
                model.AttrE = entity.AttrE;
                model.AttrF = entity.AttrF;
                model.AttrG = entity.AttrG;
                model.AttrH = entity.AttrH;
                model.AttrI = entity.AttrI;
                model.AttrJ = entity.AttrJ;
                model.AttrK = entity.AttrK;
                model.AttrL = entity.AttrL;
                model.AttrM = entity.AttrM;
                model.AttrN = entity.AttrN;
                model.AttrO = entity.AttrO;
                model.AttrP = entity.AttrP;
                model.AttrQ = entity.AttrQ;
                model.AttrR = entity.AttrR;
                model.AttrS = entity.AttrS;
                model.AttrT = entity.AttrT;
                model.AttrU = entity.AttrU;
                model.AttrV = entity.AttrV;
                model.AttrW = entity.AttrW;
                model.AttrX = entity.AttrX;
                model.AttrY = entity.AttrY;
                model.AttrZ = entity.AttrZ;
                model.CustomMember = entity.CustomMember;
                model.TimeOut = entity.TimeOut;
                model.IsDelete = entity.IsDelete;

                return model;
            }
            else
            {
                return null;
            }
        }

    }
}
